#include "Vec2.hpp"
#include "Vec3.hpp"
#include "Vec4.hpp"
#include "Mat4.hpp"
#include <string>
#include <iostream>

using gmath::Vec2f;
using gmath::Vec3f;
using gmath::Vec3i;
using gmath::Vec4f;
using gmath::Mat4f;
using std::string;
using std::cout;
using std::endl;

int main(int argc, char** argv)
{
  Vec3f v1;
  Vec3f v2(1.0f, 2.0f, 3.0f);
  Vec3f v3(1.0f);
  Vec3f v4;
  Vec4f v5;
  Vec4f v6(1.0f);
  Vec4f v7(2.0f, 3.0f, 4.0f, 5.0f);
  Vec2f v8;
  Vec2f v9(3.0f);
  Vec2f v10(10.0f, 11.0f);


  cout << "v1: " << v1 << endl;
  cout << "v2: " << v2 << endl;
  cout << "v3: " << v3 << endl;
  cout << "v1 + v2: " << (v1 + v2) << endl;
  cout << "v2 - v3: " << (v2 - v3) << endl;
  cout << "v2 * 2: " << (v2 * 2.0f) << endl;
  cout << "v2 / 2: " << (v2 / 2.0f) << endl;
  cout << "v2 * -1: " << (v2 * -1.0f) << endl;
  cout << "v4 = v2: " << (v4 = v2) << endl;
  cout << "v2: " << v2 << endl;
  cout << "v4 += v3: " << (v4 += v3) << endl;
  cout << "v2 dot v3: " << (v2.dot(v3)) << endl;
  cout << "v2 cross v3: " << (v2.cross(v3)) << endl;
  cout << "v2 length: " << (v2.length()) << endl;
  cout << "v5: " << v5 << endl;
  cout << "v6: " << v6 << endl;
  cout << "v7: " << v7 << endl;
  cout << "v8: " << v8 << endl;
  cout << "v9: " << v9 << endl;
  cout << "v10: " << v10 << endl;
  cout << "v6: " << Vec4f(v2, 1.0f) << endl;

  Mat4f m1;
  cout << "m1: " << m1 << endl; 
  Mat4f m2(1.0f);
  cout << "m2: " << m2 << endl;
  cout << "m2.mul(2): " << (m2.mul(2.0f)) << endl;
  cout << "m2 * 2: " << (m2 * 2.0f) << endl;
  Mat4f m3(3.0f);
  cout << "m3: " << m3 << endl;
  cout << "m3 * m2: " << (m3 * m2) << endl;
  cout << "m3 determinant: " << (m3.determinant()) << endl;
  cout << "m2 determinant: " << (m2.determinant()) << endl;
  cout << "m3 inverse: " << (m3.inverse()) << endl;
  
  float data[] = {
    1.0f, 2.0f, 3.0f, 4.0f,
    05.0f, 6.0f, 7.0f, 8.0f,
    9.0f, 10.0f, 00.0f, 2.0f,
    00.0f, 00.0f, 00.0f, 01.0f
  };
  Mat4f m4(data);
  cout << "m4: " << m4 << endl;
  cout << "m4 inverse: " << (m4.inverse()) << endl; 

  

  
  return 1;
}
